package com.learn.cloud.datascope;

import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.creator.hikaricp.HikariDataSourceCreator;
import com.baomidou.dynamic.datasource.processor.DsHeaderProcessor;
import com.baomidou.dynamic.datasource.processor.DsProcessor;
import com.baomidou.dynamic.datasource.processor.DsSessionProcessor;
import com.baomidou.dynamic.datasource.processor.DsSpelExpressionProcessor;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.learn.cloud.datascope.config.ClearTtlDataSourceFilter;
import com.learn.cloud.datascope.config.JdbcDynamicDataSourceProvider;
import com.learn.cloud.datascope.config.LastParamDsProcessor;
import com.learn.cloud.datascope.propertie.DruidDataSourceProperties;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.expression.BeanFactoryResolver;

import java.util.ArrayList;
import java.util.List;

/**
 * 动态数据源切换配置
 *
 * @author: MI
 * @email: 448341911@qq.com
 * @createDate: 2023/11/5 20:22
 * @updateUser: MI
 * @updateDate: 2023/11/5 20:22
 * @updateRemark: 修改内容
 * @version: v1.0
 */
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(DruidDataSourceProperties.class)
public class DynamicDataSourceAutoConfiguration {

    /**
     * 动态数据源提供者
     * @param defaultDataSourceCreator 默认数据源创建器
     * @param properties 数据源配置属性
     * @param stringEncryptor 字符串加密器
     * @return 动态数据源提供者
     */
    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator,
                                                               DruidDataSourceProperties properties,StringEncryptor stringEncryptor) {
        return new JdbcDynamicDataSourceProvider(defaultDataSourceCreator, stringEncryptor,properties);
    }

    /**
     * 默认数据源创建器
     * @param hikariDataSourceCreator Hikari数据源创建器
     * @return 默认数据源创建器
     */
    @Bean
    public DefaultDataSourceCreator defaultDataSourceCreator(HikariDataSourceCreator hikariDataSourceCreator) {
        DefaultDataSourceCreator defaultDataSourceCreator = new DefaultDataSourceCreator();
        List<DataSourceCreator> creators = new ArrayList<>();
        creators.add(hikariDataSourceCreator);
        defaultDataSourceCreator.setCreators(creators);
        return defaultDataSourceCreator;
    }


    /**
     * 获取数据源处理器
     * @return 数据源处理器
     */
    @Bean
    public DsProcessor dsProcessor(BeanFactory beanFactory) {
        DsProcessor lastParamDsProcessor = new LastParamDsProcessor();
        DsProcessor headerProcessor = new DsHeaderProcessor();
        DsProcessor sessionProcessor = new DsSessionProcessor();
        DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();
        spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));
        lastParamDsProcessor.setNextProcessor(headerProcessor);
        headerProcessor.setNextProcessor(sessionProcessor);
        sessionProcessor.setNextProcessor(spelExpressionProcessor);
        return lastParamDsProcessor;
    }
    /**
     * 清除Ttl数据源过滤器
     * @return 清除Ttl数据源过滤器
     */
    @Bean
    public ClearTtlDataSourceFilter clearTtlDsFilter() {
        return new ClearTtlDataSourceFilter();
    }
}
